package com.xwltz.core.utils;

import org.springframework.util.StringUtils;

import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.Optional;

/**
 * @description ReflectUtil
 * @information on version 1.0 be created by @xwltz at 2021/12/28 9:59
 */
@SuppressWarnings({"unchecked"})
public class ReflectUtils extends cn.hutool.core.util.ReflectUtil {
	private static final String SETTER_PREFIX = "set";

	private static final String GETTER_PREFIX = "get";

	/**
	 * 调用Getter方法.
	 * 支持多级，如：对象名.对象名.方法
	 */
	public static <E> E invokeGetter(Object obj, @Nullable String propertyName) {
		Object object = obj;
		String[] array = Optional.ofNullable(StringUtils.split(propertyName, ".")).orElse(new String[]{});
		for (String name : array) {
			String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
			object = invoke(object, getterMethodName);
		}
		return (E) object;
	}

	/**
	 * 调用Setter方法, 仅匹配方法名。
	 * 支持多级，如：对象名.对象名.方法
	 */
	public static <E> void invokeSetter(Object obj, String propertyName, E value) {
		Object object = obj;
		String[] array = Optional.ofNullable(StringUtils.split(propertyName, ".")).orElse(new String[]{});
		for (int i = 0; i < array.length; i++) {
			if (i < array.length - 1) {
				String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(array[i]);
				object = invoke(object, getterMethodName);
			} else {
				String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(array[i]);
				Method method = getMethodByName(object.getClass(), setterMethodName);
				invoke(object, method, value);
			}
		}
	}
}
